/************************* 类描述 *********************************
 * 展示服务层
 *****************************************************************
 */
package com.realgodo.site.service.application;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.orm.Page;
import org.springside.modules.orm.hibernate.DefaultEntityManager;

import com.realgodo.site.entity.application.show.Show;
import com.realgodo.site.entity.application.show.ShowModule;

@Service("showManager")
@Transactional
public class ShowManager extends DefaultEntityManager<Show, Long> {

	@Autowired
	protected SessionFactory sessionFactory;

	@Autowired
	private ShowModuleManager showModuleManager;

	/**
	 * 通过空间id获取一组展示
	 * 
	 * @param spaceId
	 * @return
	 */
	public Page<Show> findShows(Long spaceId, int maxResults) {
		Page<Show> page = new Page<Show>(maxResults);
		Criteria c = sessionFactory.getCurrentSession().createCriteria(
				Show.class);
		c.add(Restrictions.eq("space.id", spaceId));
		c.addOrder(Order.desc("pubTime"));
		return this.entityDao.findByCriteria(page, c);
	}

	/**
	 * 创建一个展示
	 * 
	 * @param show
	 * @return
	 */
	public Show createShow(Show show, List<ShowModule> modules) {
		if (null == modules || modules.isEmpty()) {
			return null;
		}
		show.setClasz(Show.class);
		Show showPersistence = (Show) this.saveMerge(show);
		for (ShowModule module : modules) {
			if (null == module) {
				continue;
			}
			if ((null != module.getPath() && !module.getPath().isEmpty())
					|| (null != module.getContent() && !module.getContent()
							.isEmpty())) {
				module.setShow(showPersistence);
				this.showModuleManager.saveMerge(module);
			}
		}

		return showPersistence;
	}

	/**
	 * 获取一个展示
	 * 
	 * @param showId
	 * @return
	 */
	public Show getShow(Long showId) {
		Show show = this.get(showId);
		List<ShowModule> modules = this.showModuleManager
				.findShowModulesByShow(showId);
		show.setShowModules(modules);
		return show;
	}

	/**
	 * 管理员获取全部展示
	 * 
	 * @param showPage
	 * @param showForm
	 * @return
	 */
	public Page<Show> findShows(Page<Show> showPage, Show showForm) {
		Criteria c = sessionFactory.getCurrentSession().createCriteria(
				Show.class);
		if (null != showForm) {
			if (null != showForm.getTitle()
					&& !"".equals(showForm.getTitle().trim())) {
				c.add(Restrictions.like("title", showForm.getTitle().trim(),
						MatchMode.ANYWHERE));
			}
			if (showForm.getPrivacy() != Show.PRIVACY_ALL) {
				c.add(Restrictions.eq("privacy", showForm.getPrivacy()));
			}
			if (showForm.getTop() != Show.TOP_ALL) {
				c.add(Restrictions.eq("top", showForm.getTop()));
			}
			if (showForm.getViedo() != Show.VIEDO_ALL) {
				c.add(Restrictions.eq("viedo", showForm.getViedo()));
			}
			if (showForm.getViedoTop() == Show.VIEDO_TOP_YES) {
				c.add(Restrictions.eq("viedoTop", showForm.getViedoTop()));
			}
			if (null != showForm.getSid()) {
				c.add(Restrictions.eq("showCatalog.id", showForm.getSid()));
			}
			if (null != showForm.getKey() && !"".equals(showForm.getKey())) {
				c.add(Restrictions.or(Restrictions.like("title", showForm
						.getKey(), MatchMode.ANYWHERE), Restrictions.like(
						"space.name", showForm.getKey(), MatchMode.ANYWHERE)));
			}
		}
		c.addOrder(Order.desc("pubTime"));
		return this.entityDao.findByCriteria(showPage, c);
	}

	public Show findTopShowViedo() {
		Show show = null;
		Show topViedoForm = new Show();
		Page<Show> topViedoPage = new Page<Show>(1);
		topViedoForm.setTop(Show.TOP_ALL);
		topViedoForm.setViedo(Show.VIEDO_YES);
		topViedoForm.setViedoTop(Show.VIEDO_TOP_YES);
		topViedoForm.setPrivacy(Show.PRIVACY_PUBLIC);
		topViedoPage = this.findShows(topViedoPage, topViedoForm);

		if (null != topViedoPage && !topViedoPage.getResult().isEmpty()) {
			show = topViedoPage.getResult().get(0);
			show.setShowModules(this.showModuleManager
					.findShowModulesByShow(show.getId()));
		}
		return show;
	}

	public Show topShow(Long id) {
		Show show = this.get(id);
		show.setTop(Show.TOP_YES);
		return (Show) this.saveMerge(show);
	}

	public Show untopShow(Long id) {
		Show show = this.get(id);
		show.setTop(Show.TOP_NOT);
		return (Show) this.saveMerge(show);
	}

	public Show topViedo(Long id) {
		Show show = this.get(id);
		show.setViedoTop(Show.VIEDO_TOP_YES);
		return (Show) this.saveMerge(show);
	}

	public Show untopViedo(Long id) {
		Show show = this.get(id);
		show.setViedoTop(Show.VIEDO_TOP_NO);
		return (Show) this.saveMerge(show);
	}

	public List<Show> findRecomandShows(int maxResult) {
		Page<Show> page = new Page<Show>(maxResult);
		Criteria c = sessionFactory.getCurrentSession().createCriteria(
				Show.class);
		c.add(Restrictions.eq("top", Show.TOP_YES));
		c.addOrder(Order.desc("pubTime"));
		return this.entityDao.findByCriteria(page, c).getResult();
	}

	public void mergeShowManager(List<Show> shows) {
		Show mergeShow = null;
		for (Show show : shows) {
			if (null != show && null != show.getId()) {
				mergeShow = this.get(show.getId());
				mergeShow.setPrivacy(show.getPrivacy());
				mergeShow.setBest(show.getBest());
				mergeShow.setMyTop(show.getMyTop());
				this.entityDao.saveMerge(mergeShow);
				mergeShow = null;
			}
		}
	}

	public Page<Show> findSpaceShows(Page<Show> showPage, Long spaceId) {
		Criteria c = sessionFactory.getCurrentSession().createCriteria(
				Show.class);
		if (null != spaceId) {
			c.add(Restrictions.eq("space.id", spaceId));
		}
		c.addOrder(Order.desc("myTop"));
		c.addOrder(Order.desc("pubTime"));
		return this.entityDao.findByCriteria(showPage, c);
	}

	@SuppressWarnings("unchecked")
	public Show getMyTopShow(Long spaceId) {
		Show myTopShow = null;
		Criteria c = sessionFactory.getCurrentSession().createCriteria(
				Show.class);
		if (null != spaceId) {
			c.add(Restrictions.eq("space.id", spaceId));
		}
		c.addOrder(Order.desc("myTop"));
		c.addOrder(Order.desc("pubTime"));
		List<Show> shows = c.list();
		if (null != shows && shows.size() > 0) {
			myTopShow = shows.get(0);
		}
		return myTopShow;
	}

	public Long getShowCount(Long spaceId) {
		Session session = this.sessionFactory.getCurrentSession();
		String hql = "select count(o) from Show o where o.space.id = "
				+ spaceId;
		Query q = session.createQuery(hql);
		return (Long) q.uniqueResult();
	}

	public Show visitShow(Long showId) {
		Show show = this.get(showId);
		show.setHit(show.getHit() + 1);
		return (Show) this.saveMerge(show);
	}

	public Long getViedosCountByCatalog(Long showCatalogId) {
		Session session = this.sessionFactory.getCurrentSession();
		String hql = "select count(o) from Show o where o.viedo = "
				+ Show.VIEDO_YES + " and o.showCatalog.id = " + showCatalogId;
		Query q = session.createQuery(hql);
		return (Long) q.uniqueResult();
	}

	/**
	 * 删除展示及展示模块
	 * 
	 * @param showId
	 */
	public void deleteShow(Long showId) {
		List<ShowModule> modules = showModuleManager
				.findShowModulesByShow(showId);
		for (ShowModule module : modules) {
			showModuleManager.delete(module.getId());
		}
		this.delete(showId);
	}
}
